package com.sailfish.springbootdemo.configs;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db4.User;
import com.sailfish.springbootdemo.service.db4.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    public MyInterceptor myInterceptor;

    @PostConstruct
    public void init() {
        myInterceptor = this;
    }

    @Value("${personal.config.jwt.expiration-time}")
    private Integer expirationTime;

    @Value("${personal.config.jwt.sign}")
    private String sign;

    private Result<?> result;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setContentType("text/html;charset=UTF-8");
        //浏览器再发送post/get请求前，会先发送options请求，然而options中没有Authorization就被拦截下来，导致之后的请求如Post/Get就不再发送。
        //options直接放行
        if (request.getMethod().equals("OPTIONS")) {//options直接放行
            return true;
        }
        try {
            //处理简单请求Access-Control-Allow-Origin
            response.setHeader("Access-Control-Allow-Origin", "*");
            String authorizationHeader = request.getHeader("Authorization"); // 获取头中token
            // 验证是否为空，格式是否满足预定要求
            if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
                String token = authorizationHeader.substring("Bearer ".length());
                // do something with the token
                //创建验证对象,这里使用的加密算法和密钥必须与生成TOKEN时的相同否则无法验证
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(sign)).build();
                //验证JWT
                DecodedJWT decodedJWT = jwtVerifier.verify(token);

                //判断时间
                Date endTime = decodedJWT.getExpiresAt();
                //SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化为 hhmmss
                if (new Date().getTime() <= endTime.getTime()) {
                    String userId = decodedJWT.getClaim("userId").asString();
                    String password = decodedJWT.getClaim("password").asString();
                    String isInner = decodedJWT.getClaim("isInner").asString();
                    String belongPcb = decodedJWT.getClaim("belongPcb").asString();
                    String belongPcba = decodedJWT.getClaim("belongPcba").asString();
                    String domainAccount = decodedJWT.getClaim("domainAccount").asString();
                    String pcbas = decodedJWT.getClaim("pcbas").asString();
                    String pcbs = decodedJWT.getClaim("pcbs").asString();
                    String ipAddress = decodedJWT.getClaim("ipAddress").asString();
                    String networkSeg = decodedJWT.getClaim("networkSeg").asString();
                    List<Integer> roleList = decodedJWT.getClaim("roleList").asList(Integer.class);

                    result = myInterceptor.userService.getUserInfoById(Integer.parseInt(userId));
                    if (result.getCode() == 200) {
                        if (((User) result.getData()).getPassword().equals(password)) {
                            UserHeader userHeader = new UserHeader();
                            userHeader.setUserId(userId);
                            userHeader.setPassword(password);
                            //userHeader.setIsInner(isInner);
                            userHeader.setBelongPcb(belongPcb);
                            userHeader.setBelongPcba(belongPcba);
                            userHeader.setDomainAccount(domainAccount);
                            userHeader.setPcbas(pcbas);
                            userHeader.setPcbs(pcbs);
                            userHeader.setRoleList(roleList);
                            userHeader.setIpAddress(ipAddress);
                            userHeader.setNetworkSeg(networkSeg);
                            UserHeaderHolder.threadLocal.set(userHeader);
                            return true;
                        }
                        response.getWriter().write("{\"code\": 50001,\"msgCn\": \"需要重新登陆\",\"msgEn\": \"Need ReLogin\",\"data\": null}");
                        response.getWriter().flush();
                        return false;
                    }
                    response.getWriter().write("{\"code\": 50001,\"msgCn\": \"需要重新登陆\",\"msgEn\": \"Need ReLogin\",\"data\": null}");
                    response.getWriter().flush();
                    return false;
                }
            }
            response.getWriter().write("{\"code\": 50001,\"msgCn\": \"需要重新登陆\",\"msgEn\": \"Need ReLogin\",\"data\": null}");
            response.getWriter().flush();
        } catch (TokenExpiredException e) {
            response.getWriter().write("{\"code\": 50001,\"msgCn\": \"需要重新登陆\",\"msgEn\": \"Need ReLogin\",\"data\": null}");
            response.getWriter().flush();
        }
        return false;
    }
}